package com.tqjc.business.interactivewithscan.core.thread.notuse;

import com.tqjc.business.interactivewithscan.consts.CoordConstant;
import com.tqjc.business.interactivewithscan.consts.DeviceEnum;
import com.tqjc.business.interactivewithscan.consts.ExceptionEnum;
import com.tqjc.business.interactivewithscan.core.data.AskData.AskData;
import com.tqjc.business.interactivewithscan.core.data.PointData.PointData;
import com.tqjc.business.interactivewithscan.core.thread.NormalThread;
import com.tqjc.business.interactivewithscan.core.thread.PTZ.DoubleTrackPZTThread;
import com.tqjc.business.interactivewithscan.core.thread.PTZ.SingleTrackPZTThread;
import com.tqjc.business.interactivewithscan.entity.*;
import com.tqjc.business.interactivewithscan.exception.CustomException;
import com.tqjc.business.interactivewithscan.service.MaterialInfoService;
import com.tqjc.business.interactivewithscan.service.ScanDeviceDataService;
import com.tqjc.business.interactivewithscan.service.UfcDeviceInfoService;
import com.tqjc.business.interactivewithscan.service.impl.ScanDeviceDataServiceImpl;
import com.tqjc.business.interactivewithscan.uils.CommonUtils;
import com.tqjc.business.interactivewithscan.uils.CoordinatesUtils;
import com.tqjc.business.interactivewithscan.uils.PTZUtils;
import com.tqjc.system.core.util.SpringUtils;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: C20005_Xianggang_new
 * @description: 单轨槽车扫描线程
 * @author: Patienyon
 * @create: 2023-11-06 20:04
 **/
//@Service("FirstSingleTrackTankScanThread")
@Slf4j
public class FirstSingleTrackTankScanThread extends NormalThread {

    private ReentrantLock lock = new ReentrantLock();


    public volatile Queue<AskData> askDataQue = new LinkedBlockingQueue<>();

    public volatile Map<String, PointData> responseMap = new LinkedHashMap<>();

    private ScanDeviceDataService scanDeviceDataService = SpringUtils.getBean(ScanDeviceDataServiceImpl.class);
    /**
     * 物料信息
     */
    @Resource
    MaterialInfoService materialInfoService;
//    private static BMaterialService materialService = ApplicationContextUtil.getBean(BMaterialService.class);
//    private static MaterialInfoService materialService = ApplicationContextUtil.getBean(BMaterialService.class);
    /**
     * 设备信息
     */
    private UfcDeviceInfoService deviceInfoService = SpringUtils.getBean(UfcDeviceInfoService.class);

    /**
     * 当前所属跨
     * 100：指定废钢跨，200：指定炉渣跨，000:转炉
     */
    private String span = "200";

    public String getSpan() {
        return span;
    }

    private Coord old;

    private ScanningData scanningData;

    public void setSpan(String span) {
        this.span = span;
    }

    public void setScanningData(ScanningData scanningData) {
        this.scanningData = scanningData;
        this.old = null;
    }


    public FirstSingleTrackTankScanThread() {
        AskData askData1 = new AskData();
        askData1.setScanType(1);
        askData1.setAskId("y212212112");
        askData1.setAreaId("1");
        askData1.setType("ss");
        addAskDataQue(askData1);
        //绑定当前的设备信息
        this.device = scanDeviceDataService.getById(100008);
        this.deviceInfo = deviceInfoService.getById(100008);
//        this.device = this.deviceInfo;
        this.start();
    }

    //    @Override
//    public void run() {
//        while (true) {
//            try {
////                checkSocket();
//
//                //TODO:测试时添加一个请求ID
//                AskData askData1 = new AskData();
//                askData1.setScanType(1);
//                askData1.setAskId("y212212112");
//                askData1.setAreaId("1");
//                askData1.setType("ss");
//                addAskDataQue(askData1);
//                log.error("添加成功");
//                Thread.sleep(1000);
//                //获取当前的请求列表
//                final Queue<AskData> tmpAskData = getAskDataQue();
//                log.error(tmpAskData.toString());
//                //假设当前的请求列表有，循环准备开始获取抓点/放点
////                while (!tmpAskData.isEmpty()) {
////                    Integer num = 0;
////                    AskData askData = tmpAskData.poll();
////
////                    log.error(askData.toString());
////
////                    //读取当前的请求
////                    //获取当前请求ID
////                    String askId = askData.getAskId();
////                    //获取当前的工作模式
////                    String type = askData.getType();
////                    //获取当前需要获取的区域ID
////                    Long areaId = Long.parseLong(askData.getAreaId());
////                    //所属跨
////                    Integer scanId = askData.getScanType();
////
////                    tmpAskData.poll();
////                    while (num < 3) {
//                //先获取扫描数据
//                Boolean scanState = getScanningDataFromPTZ();
//
////                        if(scanState){
//                //获取放点
//                List<Coord> discharges = getDischarge(scanningData);
//                System.out.println(discharges.toString());
//                if (!discharges.isEmpty()) {
////                                addResponseMap(askId, new PointData(true,"获取放点成功",discharges, new Timestamp(System.currentTimeMillis())));
//                    addResponseMap("11", new PointData(true, "获取放点成功", discharges, new Timestamp(System.currentTimeMillis())));
//                    break;
//                }
//
////                        }
////                        num++;
////                        if(num>=3){
////                            addResponseMap(askId, new PointData(false,"获取放点失败"));
////                        }
////                    }
////
////                    askDataQue.poll();
//
//
////                }
//
//                Thread.sleep(1000);
//                // 线程逻辑代码
//            } catch (Exception e) {
//                // 捕获线程异常
//                e.printStackTrace();
//                // 线程挂掉后，等待一段时间再重新启动
//                try {
//                    Thread.sleep(1000); // 可以根据需要调整等待时间
//                } catch (InterruptedException ex) {
//                    ex.printStackTrace();
//                }
//            }
//        }
//    }
    @Override
    public void run() {
        while (true) {
            try {
                checkSocket();
                //添加一个请求
                AskData askData1 = new AskData();
                askData1.setAskId("sss");
                askData1.setAreaId("7");
                addAskDataQue(askData1);
//                获取当前的请求列表
                final Queue<AskData> tmpAskData = getAskDataQue();

                System.out.println(tmpAskData.toString());
                //假设当前的请求列表有，循环准备开始获取抓点/放点
//                while (!tmpAskData.isEmpty()) {
                log.info("开始获取槽车放点");
                Integer num = 0;
                AskData askData = tmpAskData.poll();

//                    //读取当前的请求
//                    //获取当前请求ID
//                    String askId = askData.getAskId();
//                    //获取当前的工作模式
//                    String type = askData.getType();
//                    //获取当前需要获取的区域ID
//                    Long areaId = Long.parseLong(askData.getAreaId());
//                    //所属跨
//                    Integer scanId = askData.getScanType();
//
//                    tmpAskData.poll();

                //先获取扫描数据
                Boolean scanState = getScanningData();


                if (scanState) {
                    //获取放点
                    List<Coord> discharges = getDischarge(this.scanningData);
                    System.out.println(discharges);
//                        if (!discharges.isEmpty()) {
//                            addResponseMap(askId, new PointData(true, "获取放点成功", discharges, new Timestamp(System.currentTimeMillis())));
//                            break;
//                        } else {
//                            addResponseMap(askId, new PointData(false, "获取放点失败"));
//                        }

                }
//                    askDataQue.poll();


//                }

                Thread.sleep(60000);
                // 线程逻辑代码
            } catch (Exception e) {
                // 捕获线程异常
                e.printStackTrace();
                // 线程挂掉后，等待一段时间再重新启动
                try {
                    Thread.sleep(1000); // 可以根据需要调整等待时间
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    public boolean getScanningData() {
        setScanningData(null);
        NormalThread normalThread = SpringUtils.getBean(SingleTrackPZTThread.class);
        ScanningData scanningData = PTZUtils.scanning(device, normalThread.getSocketClient());
        try {
//            List<Coord> areas = CoordinatesUtils.queryArea(scanningData.getScanningArea(), device.getDeviceCode(), scanningData.getScanningDate());
            List<Coord> areas = CoordinatesUtils.queryArea(scanningData.getScanningArea(), DeviceEnum.Tanker_Wide_Track_3.getDeviceCode(), scanningData.getScanningDate());
            if (areas.size() < 4) {
//                    normalThread.setStart(false);
                return false;
            }
            List<Coord> dems = CoordinatesUtils.yuntaiScanningHandle(scanningData.getScanningDem());
            CoordinatesUtils.removeShadows(dems);
            if (dems.size() == 0) {
                return false;
            }
            int z = dems.stream().min(new CoordSort(4)).get().getZ();
            if (z < CoordConstant.Tanker_Safe_Height - 1500) {
//                    yuntaiThread.setStart(false);
                return false;
            }
//            boolean b = deviceThread.updateDischarge(sameTask, scanningData);
//            if (!b) {
//                System.out.println("ssss");
////                    yuntaiThread.setStart(false);
//                return false;
//            }
//                deviceThread.setOldTask(new ArrayList<>(sameTask));
        } catch (CustomException e) {
            System.err.println("【" + device.getDeviceName() + "】" + e.getMsg());
//                yuntaiThread.setStart(false);
            return false;
        } catch (Exception e) {
            e.printStackTrace();
//                yuntaiThread.setStart(false);
            return false;
        }
        this.setScanningData(scanningData);
//            yuntaiThread.setStart(false);

        CommonUtils.sleep(1000);
        return true;
    }

    @Override
    public void heartbeat(DeviceSocketClient socketClient) {

        NetSocket socket = socketClient.getSocket();
        System.err.println("【" + device.getDeviceName() + "】首次发送心跳！");
        socket.write(Buffer.buffer("HB"));
        socketClient.getVertx().setPeriodic(1000 * 10, t -> {
            socket.write(Buffer.buffer("HB"));
        });
    }

    public synchronized void addAskDataQue(AskData askData) {
        askDataQue.add(askData);
    }

    public synchronized void addResponseMap(String askId, PointData pointData) {
        responseMap.put(askId, pointData);
    }

    public boolean getScanningDataFromPTZ() {
        // 获取同跨天车任务
        setScanningData(null);
        NormalThread normalThread = SpringUtils.getBean(SingleTrackPZTThread.class);
//        NormalThread normalThread1 = SpringUtils.getBean(DoubleTrackPZTThread.class);
//        ScanningData scanningData = PTZUtils.scanning(device, normalThread.getSocketClient());
        ScanningData scanningData = PTZUtils.scanning(normalThread.getDevice(), normalThread.getSocketClient());
        setScanningData(scanningData);
//        ScanningData scanningData1 = PTZUtils.scanning(normalThread1.getDevice(), normalThread1.getSocketClient());
        try {
            List<Coord> areas = CoordinatesUtils.queryArea(scanningData.getScanningArea(), DeviceEnum.Tanker_Double_Track_1.getDeviceCode(), scanningData.getScanningDate());
            if (areas.size() < 4) {
//                    normalThread.setStart(false);
                return false;
            }
            List<Coord> dems = CoordinatesUtils.yuntaiScanningHandle(scanningData.getScanningDem());
            CoordinatesUtils.removeShadows(dems);
            if (dems.size() == 0) {
                return false;
            }
            int z = dems.stream().min(new CoordSort(4)).get().getZ();
            if (z < CoordConstant.Tanker_Safe_Height - 1500) {
//                    yuntaiThread.setStart(false);
                return false;
            }
//            boolean b = deviceThread.updateDischarge(sameTask, scanningData);
//            if (!b) {
//                System.out.println("ssss");
////                    yuntaiThread.setStart(false);
//                return false;
//            }
//                deviceThread.setOldTask(new ArrayList<>(sameTask));
        } catch (CustomException e) {
            System.err.println("【" + device.getDeviceName() + "】" + e.getMsg());
//                yuntaiThread.setStart(false);
            return false;
        } catch (Exception e) {
            e.printStackTrace();
//                yuntaiThread.setStart(false);
            return false;
        }
        this.setScanningData(scanningData);
//            yuntaiThread.setStart(false);

        CommonUtils.sleep(1000);
        return true;
    }

    public List<Coord> getDischarge(ScanningData scanningData) {
        List<Coord> areas = CoordinatesUtils.queryArea(scanningData.getScanningArea(), device.getDeviceCode());
        List<Coord> dems = CoordinatesUtils.yuntaiScanningHandle(scanningData.getScanningDem());
        areas.sort(new CoordSort(3));
        int may = areas.get(2).getY();
        int miy = areas.get(1).getY();
        areas.sort(new CoordSort(2));
        int max = areas.get(2).getX();
        int mix = areas.get(1).getX();
        if (may - deviceInfo.getWidth() < miy) {
            this.lock.unlock();
            throw new CustomException(ExceptionEnum.TANKER_INFO_ERROR);
        }
        int y = (may + may - deviceInfo.getWidth()) / 2;
        int x = (max + mix) / 2;
        int tx = deviceInfo.getLength() / 2;
        int ty = deviceInfo.getWidth() / 2 - CoordConstant.Tanker_Safe_Distance;
        Coord coord = new Coord(x, y, 0);
        QuadrilateralVertex vertex = CoordinatesUtils.queryVertex(coord, tx, ty);
        List<Coord> screens = CoordinatesUtils.screenDesignationRegion(vertex, dems);
        //去除阴影
        CoordinatesUtils.removeShadows(screens);

        // 查询物料信息
        int type = Integer.parseInt(this.getSpan()) / 100;
        // 一号先卸
        Coord discharge1 = CoordinatesUtils.dischargeCoord(new ArrayList<>(screens), vertex, this.deviceInfo.getLength(), this.deviceInfo.getWidth(), true);
        Coord discharge2 = CoordinatesUtils.dischargeCoord(new ArrayList<>(screens), vertex, this.deviceInfo.getLength(), this.deviceInfo.getWidth(), true);
        Coord discharge3 = CoordinatesUtils.dischargeCoord(new ArrayList<>(screens), vertex, this.deviceInfo.getLength(), this.deviceInfo.getWidth(), true);
        Coord discharge4 = CoordinatesUtils.dischargeCoord(new ArrayList<>(screens), vertex, this.deviceInfo.getLength(), this.deviceInfo.getWidth(), true);
        System.err.println("【" + device.getDeviceName() + "】本次四个放料点如下：");
        System.err.println("【" + device.getDeviceName() + "】一号先卸：" + discharge1);
        System.err.println("【" + device.getDeviceName() + "】二号后卸：" + discharge2);
        System.err.println("【" + device.getDeviceName() + "】二号先卸：" + discharge3);
        System.err.println("【" + device.getDeviceName() + "】一号后卸：" + discharge4);
        return new ArrayList<Coord>() {{
            add(discharge1);
            add(discharge2);
            add(discharge3);
            add(discharge4);
        }};
    }

    private void takeCenter(Coord coord, int center) {
        if (coord != null) {
            coord.setX(center);
        }
    }
}
